package cn.blnp.net.flowable.transfer.sequence.defaults;

import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * <h3>顺序流-默认顺序流</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/5/19 15:23
 */
@Slf4j
@SpringBootTest
public class DefaultSeqTest {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    /**
     *  <h2>默认顺序流</h2>
     *  <p>
     *      在BPMN 2.0规范中，所有的任务和网关都可以设置一个默认顺序流。当节点的其他外出顺序流的条件都不满足时，工作流引擎将会选择默认顺序流作为外出顺序流继续执行，此时默认顺序流的条件设置不会生效。
     *  默认顺序流通过对应节点的default属性定义。下面看一个为排他网关设置默认顺序流的使用示例：
     *      <b>流程定义文件：</b>{@link flow/defaultSequenceFlow.bpmn20.xml}<br/>
     *      <b>流程预览图：</b><br/>
     *      <img src="https://cdn4.winhlb.com/2025/05/19/682ae2b4455cb.png" />
     *  </p>
     **/
    @Test
    public void test() {
        Deployment deploy = repositoryService.createDeployment()
                .name("默认顺序流案例")
                .addClasspathResource("flow/defaultSequenceFlow.bpmn20.xml")
                .deploy();
        log.info("部署流程定义：{}", deploy.getId());
        ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        log.info("流程定义编号：{}", procDef.getId());
        //设置流程变量
        Map<String, Object> varMap = MapUtil.builder(new HashMap<String, Object>())
                .put("condition1", false)
                .put("condition3", false)
                .build();
        //启动流程实例
        ProcessInstance procInst = runtimeService.startProcessInstanceById(procDef.getId(), varMap);
        TaskQuery taskQuery = taskService.createTaskQuery()
                .processInstanceId(procInst.getId());

        //查询并完成第一个任务
        Task firstTask = taskQuery.singleResult();
        log.info("即将完成第一个任务，当前任务名称：{}", firstTask.getName());

        /**
         *  演示结果：
         *  2025-05-19 16:09:06.507  INFO 43264 --- [           main] c.b.n.f.t.s.defaults.DefaultSeqTest      : 部署流程定义：889814aa-3488-11f0-ab96-50ebf6ec8f6d
         * 2025-05-19 16:09:06.510  INFO 43264 --- [           main] c.b.n.f.t.s.defaults.DefaultSeqTest      : 流程定义编号：defaultSequenceFlow:2:88dbfb7d-3488-11f0-ab96-50ebf6ec8f6d
         * 2025-05-19 16:09:06.591  INFO 43264 --- [           main] c.b.n.f.t.s.defaults.DefaultSeqTest      : 即将完成第一个任务，当前任务名称：用户任务2
         **/
    }
}
